package com.zlsy.learning.leetcode.queue;

/**
 * @author zhouliang
 * @date 2020/8/14 8:52
 */
public class BlockQueue {
  private Object[] items;
  private int tail = 0;
  private int head = 0;
  private int size = 0;

  private BlockQueue() {}

  public BlockQueue(int capital) {
    items = new Object[capital];
    size = capital;
  }

  public static void main(String[] args) throws InterruptedException {
    BlockQueue blockQueue = new BlockQueue(3);
    new Thread(
            () -> {
              for (int i = 0; i < 30; i++) {
                try {
                  System.out.println(String.format("生产者:%s", i));
                  blockQueue.equeue(i);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            })
        .start();
    Thread.sleep(10);
    new Thread(
            () -> {
              for (int i = 0; i < 30; i++) {
                try {
                  System.out.println(String.format("消费者:%s", i));
                  blockQueue.dqueue();
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            })
        .start();
  }

  public boolean equeue(Object item) throws InterruptedException {
    synchronized (items) {
      if ((tail + 1) % size == head) {
        System.err.println("队列已满！");
        items.wait();
        return false;
      } else {
        items[tail] = item;
        tail = (tail + 1) % size;
        items.notify();
        return true;
      }
    }
  }

  public Object dqueue() throws InterruptedException {
    synchronized (items) {
      if (tail == head) {
        System.err.println("队列已空！");
        items.wait();
        return null;
      } else {
        Object ret = items[head];
        head = (head + 1) % size;
        items.notify();
        return ret;
      }
    }
  }
}
